package com.android.lovely.util

import android.content.Context
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Paint
import android.graphics.PorterDuff
import android.graphics.PorterDuffXfermode
import android.graphics.Rect
import android.graphics.RectF
import android.os.Build
import android.renderscript.Allocation
import android.renderscript.Element
import android.renderscript.RenderScript
import android.renderscript.ScriptIntrinsicBlur
import androidx.annotation.FloatRange
import androidx.annotation.RequiresApi

object BitmapUtil {

    fun blur(
        context: Context,
        srcBitmap: Bitmap?,
        @FloatRange(from = 0.0, to = 25.0) radius: Float,
        @FloatRange(from = 0.0) cornerRadius: Float = 0f
    ): Bitmap? {
        if (srcBitmap == null) {
            return null
        }

        val blurredBitmap = blurWithRenderScript(context, srcBitmap, radius)

        return if (cornerRadius > 0) {
            getRoundedCornerBitmap(blurredBitmap, cornerRadius)
        } else {
            blurredBitmap
        }
    }

    @RequiresApi(Build.VERSION_CODES.S)
    private fun blurWithSystemApi(
        context: Context,
        bitmap: Bitmap,
        @FloatRange(from = 0.0, to = 100.0) radius: Float
    ): Bitmap {
        // 创建一个与原始 Bitmap 尺寸相同的输出 Bitmap
//        val outputBitmap = Bitmap.createBitmap(bitmap.width, bitmap.height, bitmap.config)
//        val canvas = Canvas(outputBitmap)
//
//        // 创建 Paint 对象应用 RenderEffect
//        val paint = Paint()
//        val renderEffect = RenderEffect.createBlurEffect(radius, radius, Shader.TileMode.CLAMP)
//
//        paint.setRenderEffect(renderEffect) // 使用 Paint 应用 RenderEffect
//
//        // 在 Canvas 上绘制原始 Bitmap
//        canvas.drawBitmap(bitmap, 0f, 0f, paint)
        return bitmap
    }

    @Suppress("DEPRECATION")
    private fun blurWithRenderScript(
        context: Context,
        srcBitmap: Bitmap,
        @FloatRange(from = 0.0, to = 25.0) radius: Float
    ): Bitmap {
        var rs: RenderScript? = null
        var input: Allocation? = null
        var output: Allocation? = null
        var blur: ScriptIntrinsicBlur? = null
        var tempBitmap: Bitmap? = null
        try {
            val width = srcBitmap.width / 2
            val height = srcBitmap.height / 2
            tempBitmap = Bitmap.createScaledBitmap(srcBitmap, width, height, false)
            val currentBitmap = tempBitmap
            val outputBitmap = Bitmap.createBitmap(width, height, srcBitmap.config?: Bitmap.Config.ARGB_8888)
            rs = RenderScript.create(context)
            rs.messageHandler = RenderScript.RSMessageHandler()
            blur = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs))
            input = Allocation.createFromBitmap(rs, currentBitmap)
            output = Allocation.createTyped(rs, input.type)
            blur.setRadius(radius)
            for (i in 0 until 2) {
                blur.setInput(input)
                blur.forEach(output)
                output.copyTo(outputBitmap)
                if (i < 2 - 1) {
                    input?.destroy()
                    input = Allocation.createFromBitmap(rs, outputBitmap)
                }
            }
            val resultBitmap = Bitmap.createScaledBitmap(outputBitmap, srcBitmap.width, srcBitmap.height, false)
            return resultBitmap
        } finally {
            rs?.destroy()
            input?.destroy()
            output?.destroy()
            blur?.destroy()
            tempBitmap?.recycle()
        }
    }

    private fun getRoundedCornerBitmap(bitmap: Bitmap, cornerRadius: Float): Bitmap {
        val output = Bitmap.createBitmap(bitmap.width, bitmap.height, Bitmap.Config.ARGB_8888)
        val canvas = Canvas(output)

        val color = -0xbdbdbe
        val paint = Paint()
        val rect = Rect(0, 0, bitmap.width, bitmap.height)
        val rectF = RectF(rect)

        paint.isAntiAlias = true
        canvas.drawARGB(0, 0, 0, 0)
        paint.color = color
        canvas.drawRoundRect(rectF, cornerRadius, cornerRadius, paint)

        paint.xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC_IN)
        canvas.drawBitmap(bitmap, rect, rect, paint)

        return output
    }
}